package com.ezlcp.form.service;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ezlcp.commons.base.db.BaseDao;
import com.ezlcp.commons.base.db.BaseService;
import com.ezlcp.commons.base.entity.JsonResult;
import com.ezlcp.commons.constant.Constants;
import com.ezlcp.commons.constant.DataTypeEnum;
import com.ezlcp.commons.constant.InputSourceEnum;
import com.ezlcp.commons.constant.StatusEnum;
import com.ezlcp.commons.service.impl.SuperServiceImpl;
import com.ezlcp.commons.tool.Convert;
import com.ezlcp.commons.tool.IdGenerator;
import com.ezlcp.commons.tool.StringUtils;
import com.ezlcp.commons.utils.ContextUtil;
import com.ezlcp.form.db.DBHelper;
import com.ezlcp.form.entity.EntityCol;
import com.ezlcp.form.entity.Form;
import com.ezlcp.form.entity.FormControl;
import com.ezlcp.form.mapper.FormMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * [表单（主表）定义]业务服务类
 */
@Service
public class FormServiceImpl extends SuperServiceImpl<FormMapper, Form> implements BaseService<Form> {
    /***
     * 表单页面JSON的存储KEY
     */
    public static final String FORM_JSON_KEY = "formJson";
    public static final String FORM_ID_KEY = "fmId";
    public static final String WIDGET_LIST_KEY = "widgetList";
    public static final String FORM_CONFIG_KEY = "formConfig";

    public static final String CTRL_TYPE_TEXT = "input";
    public static final String CTRL_TYPE_DATE = "date";
    public static final String CTRL_TYPE_SELECT = "select";
    public static final String CTRL_TYPE_TEXTAREA = "textarea";

    public static final String DATE_CONTROL_FORMAT_DEFAULT = "YYYY-MM-DD";
    public static final String DATE_CONTROL_FORMAT_DATETIME = "YYYY-MM-DD HH:mm:ss";

    public static final String REF_ENT_ID_KEY = "refEntId";
    public static final String OPTION_ITEMS_KEY = "optionItems";
    @Resource
    public LogService logService;
    @Resource
    private FormMapper formMapper;
    @Resource
    private EntityServiceImpl entityService;
    @Resource
    private ModuleServiceImpl moduleService;
    @Resource
    private FormControlServiceImpl formControlService;

    /***
     * 获取自定义表单的修改页面的初始数据
     * @param formId 表单主键值
     * @param pkId 记录主键值
     * @return com.ezlcp.commons.base.entity.JsonResult
     * @author Elwin ZHANG
     * @date 2023/11/21 15:57
     */
    public JsonResult getFormData(String formId, String pkId, boolean isPreview) {
        JSONObject data = new JSONObject();
        var result = JsonResult.Success("common.handleSuccess");
        var form = BaseService.super.get(formId);
        if (form == null || StringUtils.isEmpty(form.getEntId())) {
            return JsonResult.Fail("common.paramError");
        }
        String entId = form.getEntId();
        var entity = entityService.getBaseMapper().selectById(entId);
        if (entity == null) {
            return JsonResult.Fail("common.paramError");
        }
        var client = DBHelper.getDbClient(entity.getDsId());
        //如果主键不为空，则查询该条记录
        if (StringUtils.isNotEmpty(pkId)) {
            var formData = client.getById(entity.getTableName(), pkId);
            if (formData == null || formData.isEmpty()) {
                //查询表单记录失败
                return JsonResult.Fail("form.getByIdFail");
            }
            data.put("formData", formData);
        }
        //表单页面JSON
        String jsonStr = form.getContent();
        String tmpJson = form.getTempContent();
        //如果在预览状态下，取临时的页面JSON
        if (isPreview && StringUtils.isNotEmpty(tmpJson) && !"{}".equals(tmpJson)) {
            jsonStr = tmpJson;
        }
        if (StringUtils.isEmpty(jsonStr) || "{}".equals(jsonStr)) {
            data.put(FORM_JSON_KEY, new JSONObject());
        } else {
            var object = JSONObject.parseObject(jsonStr);
            data.put(FORM_JSON_KEY, object.getJSONObject(FORM_JSON_KEY));
        }
        JSONObject formObject = new JSONObject();
        formObject.put("entId", form.getEntId());
        formObject.put("fmId", form.getFmId());
        formObject.put("fmType", form.getFmType());
        formObject.put("moduleId", form.getModuleId());
        formObject.put("fmName", form.getFmName());
        formObject.put("hkName", form.getHkName());
        formObject.put("enName", form.getEnName());
        formObject.put("status", form.getStatus());
        formObject.put("isReadonly", form.getIsReadonly());
        formObject.put("width", form.getWidth());
        formObject.put("height", form.getHeight());
        data.put("formDef", formObject);
        //TODO 子表数据
        result.setData(data);
        return result;
    }

    /***
     * 保存表单记录
     * @param formId 表单ID
     * @param record 记录数据
     */
    public JsonResult saveFormData(String formId, JSONObject record) {
        JSONObject logData = new JSONObject();
        logData.put("new", record);
        var form = BaseService.super.get(formId);
        if (form == null || StringUtils.isEmpty(form.getEntId())) {
            return JsonResult.Fail("common.paramError");
        }
        String entId = form.getEntId();
        var entity = entityService.getEntityAndCols(entId);
        if (entity == null || entity.getCols() == null || entity.getCols().isEmpty()) {
            return JsonResult.Fail("common.paramError");
        }
        var client = DBHelper.getDbClient(entity.getDsId());
        String pkId = record.getString("id");

        //新增
        if (StringUtils.isEmpty(pkId)) {
            boolean result = client.insert(entity, record);
            if (!result) {
                return JsonResult.Fail("common.addFail");   //新增失败
            }
        } else {
            var oldRecord = client.getById(entity.getTableName(), pkId);
            logData.put("old", oldRecord);
            Integer oldSeq = (Integer) oldRecord.get(Constants.COL_SEQ);
            if (oldSeq != null && oldSeq != record.getIntValue(Constants.COL_SEQ)) {
                return JsonResult.Fail("common.dataChange");
            }
            boolean result = client.update(entity, record, pkId);
            if (!result) {
                return JsonResult.Fail("common.updFail");   //修改失败
            }
        }

        logService.saveSystemLog("CustomForm", "save", formId, JSON.toJSONString(logData));
        return JsonResult.Success("common.handleSuccess");
    }

    /**
     * 删除表单相关实体的记录
     *
     * @param formId 表单ID
     * @param pkId   记录ID
     * @return com.ezlcp.commons.base.entity.JsonResult
     */
    public JsonResult delFormData(String formId, String pkId) {
        var form = BaseService.super.get(formId);
        if (form == null || StringUtils.isEmpty(form.getEntId())) {
            return JsonResult.Fail("common.paramError");
        }
        String entId = form.getEntId();
        var entity = entityService.getBaseMapper().selectById(entId);
        if (entity == null) {
            return JsonResult.Fail("common.paramError");
        }
        String tableName = entity.getTableName();
        var client = DBHelper.getDbClient(entity.getDsId());
        var oldRecord = client.getById(entity.getTableName(), pkId);
        //逻辑删除
        boolean result = client.tombstoneById(tableName, pkId);
        if (!result) {
            //逻辑删除失败后，尝试物理删除
            result = client.deleteById(tableName, pkId);
        }
        if (!result) {
            return JsonResult.Fail("common.delFail");   //删除失败
        }
        logService.saveSystemLog("CustomForm", "delete", formId, JSON.toJSONString(oldRecord));
        return JsonResult.Success("common.handleSuccess");
    }

    @Override
    public Form get(Serializable id) {
        var form = BaseService.super.get(id);
        if (form != null) {
            var list = getControls(form.getFmId());
            if (list != null && list.size() > 0) {
                form.setControls(list);
            }
            //查询模块名和实体名
            var entity = entityService.getBaseMapper().selectById(form.getEntId());
            if (entity != null) {
                form.setEntityName(entity.getEntName());
                form.setEnEntityName(entity.getEnName());
                form.setHkEntityName(entity.getHkName());
            }
            var module = moduleService.getBaseMapper().selectById(form.getModuleId());
            if (module != null) {
                form.setModuleName(module.getModuleName());
                form.setEnModuleName(module.getEnName());
                form.setHkModuleName(module.getHkName());
            }
        }
        return form;
    }

    /***
     * 查询某实体对应的所有发布的表单
     * @param entId 实体ID
     */
    public List<Form> getListByEntId(String entId) {
        LambdaQueryWrapper<Form> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(Form::getFmId, Form::getFmName, Form::getHkName, Form::getEnName, Form::getFmType, Form::getIsReadonly);
        wrapper.eq(Form::getEntId, entId).eq(Form::getStatus, Constants.SHORT1);
        wrapper.orderByDesc(Form::getCreateTime);
        return this.formMapper.selectList(wrapper);
    }

    /***
     * 查询表单的控件
     * @param fmId 表单ID
     * @author Elwin ZHANG
     * @date 2023/11/1 10:51
     */
    public List<FormControl> getControls(String fmId) {
        QueryWrapper<FormControl> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(FormControl::getFormId, fmId).orderByAsc(FormControl::getColOrder);
        return formControlService.getBaseMapper().selectList(wrapper);
    }

    /***
     * 发布表单
     * @param formId 表单ID
     */
    public JsonResult publish(String formId) {
        var form = this.formMapper.selectById(formId);
        if (form == null || form.getStatus() == 4) {
            return JsonResult.Fail("common.paramError");
        }
        form.setSeq(form.getSeq() + 1);
        //重新发布
        if (form.getStatus() == 1) {
            form.setContent(form.getTempContent());
            form.setVer(form.getVer() + 1);
        } else {
            //首次发布
            form.setTempContent(form.getContent());
            form.setStatus(Constants.SHORT1);
            form.setVer(1);
        }
        formMapper.updateById(form);
        return JsonResult.Success("common.handleSuccess");
    }

    /***
     * 如果新增的控件，生成控件ID
     * @param controls 表单控件集合
     */
    private void setNewControlId(List<FormControl> controls, String formId) {
        for (var control : controls) {
            if (StringUtils.isEmpty(control.getControlId())) {
                control.setControlId(IdGenerator.getIdStr());
                control.setFormId(formId);
                String settings = control.getExtSettings();
                if (StringUtils.isEmpty(settings)) {
                    control.setExtSettings("{\"clearable\":true}");
                }
            }
        }
    }

    /***
     * @description 保存表单
     * @param form 表单对象
     * @param delControlIds 要删除的控件ID
     */
    @Transactional
    public JsonResult saveForm(Form form, String delControlIds) {
        String strControls = JSON.toJSONString(form.getControls());
        var controls = JSON.parseArray(strControls, FormControl.class);
        String formId = form.getFmId();
        if (form.isRetrieve()) {
            formControlService.delByFormId(formId);
            form.setContentModified(Constants.SHORT0);
            delControlIds = "";
            setNewControlId(controls, formId);
            formControlService.saveBatch(controls);
        } else {
            //更新旧的控件
            var olds = controls.stream().filter(control -> StringUtils.isNotEmpty(control.getControlId()))
                    .collect(Collectors.toList());
            if (olds != null && !olds.isEmpty()) {
                formControlService.updateBatchById(olds);
            }
            //插入新控件
            var news = controls.stream().filter(control -> StringUtils.isEmpty(control.getControlId()))
                    .collect(Collectors.toList());
            if (news != null && !news.isEmpty()) {
                setNewControlId(news, formId);
                formControlService.saveBatch(news);
            }
        }
        //页面没有手工修改过，则自动重新生成页面
        if (form.getContentModified() == 0) {
            //生成默认的表单页面内容
            var widgetList = generateJson(form, controls);
            JSONObject content = JSONObject.parse(form.getContent());
            //已发布
            if (form.getStatus() == Constants.SHORT1) {
                String tmpContent = form.getContent();
                if (StringUtils.isNotEmpty(tmpContent) && !"{}".equals(tmpContent)) {
                    content = JSONObject.parse(tmpContent);
                }
            }
            var formJson = content.getJSONObject(FORM_JSON_KEY);
            formJson.put(WIDGET_LIST_KEY, widgetList);
            var formConfig = formJson.getJSONObject(FORM_CONFIG_KEY);
            formConfig.put("layoutType", form.isPC() ? "PC" : "H5");
            String labelWidth = form.getLabelWidth();
            if (StringUtils.isEmpty(labelWidth)) {
                labelWidth = "";
            }
            labelWidth = labelWidth.toLowerCase().replaceAll("px", "");
            int intWidth = Convert.strToInt(labelWidth, 120);
            formConfig.put("labelWidth", intWidth);
            String newContent = content.toString();
            if (form.getStatus() == Constants.SHORT1) {
                form.setTempContent(newContent);
            } else if (form.getStatus() == Constants.SHORT0) {
                form.setContent(newContent);
            }
        }
        form.setSeq(form.getSeq() + 1);
        formMapper.updateById(form);
        //处理删除控件
        if (StringUtils.isEmpty(delControlIds)) {
            return JsonResult.Success("common.handleSuccess");
        }
        var arrIds = delControlIds.split(",");
        if (arrIds.length == 0) {
            return JsonResult.Success("common.handleSuccess");
        }
        formControlService.removeBatchByIds(Arrays.asList(arrIds));
        return JsonResult.Success("common.handleSuccess");
    }

    /***
     * 保存表单页面JSON
     * @param form 表单对象
     * @param json VUE页面JSON
     */
    public void saveFormJson(Form form, JSONObject json) {
        form.setSeq(form.getSeq() + 1);
        String strContent = form.getContent();
        JSONObject content = JSONObject.parse(strContent);
        //已发布
        if (form.getStatus() == 1) {
            String tmpContent = form.getContent();
            if (StringUtils.isNotEmpty(tmpContent) && !"{}".equals(tmpContent)) {
                content = JSONObject.parse(tmpContent);
            }
            content.put(FORM_JSON_KEY, json);
            form.setTempContent(content.toString());
        } else if (form.getStatus() == 0) {
            content.put(FORM_JSON_KEY, json);
            form.setContent(content.toString());
        }
        form.setContentModified(Constants.SHORT1); //页面手工修改过
        this.formMapper.updateById(form);
    }

    /***
     * 删除表单
     * @param form 表单对象
     */
    public JsonResult deleteForm(Form form) {
        JsonResult result = JsonResult.getSuccessResult("common.handleSuccess");
        //TODO 检查是否被列表或流程引用
        if (form.getStatus() == 4) {
            return result;
        }
        form.setStatus((short) 4);
        form.setSeq(form.getSeq() + 1);
        this.formMapper.updateById(form);
        return result;
    }

    /***
     * 根据实体列重新生成表单控件（一般用于实体字段修改之后）
     * @param formId 表单Id
     * @param entityId 实体ID
     */
    public JsonResult getControlsFromEntity(String formId, String entityId) {
        var cols = entityService.getEntityCols(entityId);
        if (cols == null || cols.isEmpty()) {
            return JsonResult.Fail("common.paramError");
        }
        var controls = generateFormControls(formId, cols, false);
        JsonResult result = JsonResult.getSuccessResult("common.handleSuccess");
        result.setData(controls);
        return result;
    }

    /***
     * @description 由实体生成表单
     * @param entityId 实体ID
     * @param moduleId 模块ID
     * @param fmType 表单类型
     * @param fmCols 每个显示几个字段
     * @author Elwin ZHANG
     * @date 2023/10/9 14:39
     */
    @Transactional
    public JsonResult createFromEntity(String entityId, String moduleId, int fmType, int fmCols) {
        var entity = entityService.getById(entityId);
        if (entity == null || !moduleId.equals(entity.getModuleId()) || entity.getStatus() != StatusEnum.enable.getValue()) {
            return JsonResult.Fail("common.paramError");
        }
        String entId = entity.getEntId();
        var cols = entityService.getEntityCols(entId);
        if (cols == null || cols.isEmpty()) {
            return JsonResult.Fail("common.paramError");
        }
        String tenantId = ContextUtil.getCurrentTenantId();
        //生成并保存表单对象
        Form form = new Form();
        String formId = IdGenerator.getIdStr();
        form.setPkId(formId);
        form.setEntId(entityId).setModuleId(moduleId);
        form.setFmType(fmType == Form.TYPE_PC ? Form.TYPE_PC : Form.TYPE_H5);
        form.setFmCols((short) fmCols);
        if (fmCols < 1 || fmCols > 4) {
            form.setFmCols((short) (fmType == Form.TYPE_PC ? 2 : 1));
        }
        form.setFmName(entity.getEntName()).setHkName(entity.getHkName()).setEnName(entity.getEnName());
        form.setWidth((short) 800).setHeight((short) 600);
        form.setRowGutter(20).setLabelStyle(Constants.SHORT1);
        form.setSubTables(Constants.SHORT0).setVer(0).setContentModified(Constants.SHORT0);
        form.setIsBuildIn(Constants.SHORT0).setIsReadonly(Constants.SHORT0).setStatus(Constants.SHORT0);
        form.setTenantId(tenantId);
        form.setFontSize("12px");
        form.setLabelWidth("120px");
        form.setIcon("vaadin:form");
        form.setContent("{\"widgetList\": []," +
                "  \"formConfig\": {" +
                "    \"labelWidth\": 120," +
                "    \"labelPosition\": \"left\"," +
                "    \"labelAlign\": \"label-left-align\",\n" +
                "    \"layoutType\": \"" + (form.isPC() ? "PC" : "H5") + "\"," +
                "    \"jsonVersion\": 3" +
                "  }" +
                "}");
        this.insert(form);
        //生成字段控件, 批量保存
        List<FormControl> controls = generateFormControls(formId, cols, true);
        formControlService.saveBatch(controls);
        //生成默认的表单页面内容
        var widgetList = generateJson(form, controls);
        JSONObject content = JSONObject.parse(form.getContent());
        content.put(WIDGET_LIST_KEY, widgetList);
        JSONObject object = new JSONObject();
        object.put(FORM_JSON_KEY, content);
        form.setContent(object.toString());
        form.setSeq(1);
        form.setVer(0);
        formMapper.updateById(form);
        return JsonResult.Success("common.handleSuccess");
    }

    /***
     * 根据实体列定义，自动生动表单控件
     * @param fmId 表单Id
     * @param cols 实体列集合
     * @param needPk 是否需要生成主键
     * @return java.util.List<com.ezlcp.form.entity.FormControl>
     */
    public List<FormControl> generateFormControls(String fmId, List<EntityCol> cols, boolean needPk) {
        List<FormControl> controls = new ArrayList<>();
        int index = 1;
        for (var col : cols) {
            if (Constants.COL_TENANT_ID.equals(col.getFieldName())) {
                continue;
            }
            FormControl control = new FormControl();
            if (needPk) {
                control.setPkId(IdGenerator.getIdStr());
            }
            control.setFormId(fmId).setColId(col.getColId()).setTenantId(ContextUtil.getCurrentTenantId());
            control.setLabelText(col.getShowName()).setLabelHk(col.getHkName()).setLabelEn(col.getEnName());
            control.setControlName(col.getFieldName()).setColSpans(Constants.SHORT1);
            control.setSubTable(Constants.SHORT0).setColOrder((short) (index * 10));
            index++;
            control.setIsReadonly(Constants.SHORT0).setIsHide(Constants.SHORT0);

            JSONObject extSettings = new JSONObject();
            extSettings.put("clearable", true);
            if (col.getIsPk() == 1 || col.getIsBuildIn() == 1) {
                control.setIsReadonly(Constants.SHORT1);
                extSettings.put("clearable", false);
            }
            if (col.getIsPk() == 1 || col.getIsHide() == 1) {
                control.setIsHide(Constants.SHORT1);
            }
            control.setIsRequired(col.getIsRequired());
            control.setDefaultVal(col.getDefaultVal());
            //'style','title'
            control.setPlaceholder("").setIsExport(Constants.SHORT1);
            //根据字段类型，默认相应的控件类型
            control.setControlType(CTRL_TYPE_TEXT);
            control.setMaxLength(col.getColLength().intValue());
            if (control.getIsReadonly() == 0 && control.getIsHide() == 0) {
                String colType = col.getColType();
                if (DataTypeEnum.Date.getValue().equals(colType) || DataTypeEnum.Datetime.getValue().equals(colType)) {
                    control.setControlType(CTRL_TYPE_DATE);
                    if (DataTypeEnum.Date.getValue().equals(colType)) {
                        extSettings.put("format", DATE_CONTROL_FORMAT_DEFAULT);
                    } else {
                        extSettings.put("format", DATE_CONTROL_FORMAT_DATETIME);
                    }
                } else if (DataTypeEnum.Text.getValue().equals(colType) || DataTypeEnum.LongText.getValue().equals(colType)) {
                    control.setControlType(CTRL_TYPE_TEXTAREA);
                    control.setMaxLength(-1);
                } else if (DataTypeEnum.VarChar.getValue().equals(colType) && col.getColLength() > 149) {
                    control.setControlType(CTRL_TYPE_TEXTAREA);
                } else if (StringUtils.isNotEmpty(col.getRefEntId())) {
                    control.setControlType(CTRL_TYPE_TEXT);
                    extSettings.put(REF_ENT_ID_KEY, col.getRefEntId());
                }
            }
            if (StringUtils.isNotEmpty(col.getRefSerialNo())) {
                control.setIsReadonly(Constants.SHORT1);
            }
            //状态字段为下拉框
            if (Constants.COL_STATUS.equals(col.getFieldName())) {
                control.setControlType(CTRL_TYPE_SELECT);
                String statusList = "[" +
                        "{\"value\": \"0\",\"label\": \"草稿-Draft\" }," +
                        "{\"value\": \"1\",\"label\": \"已发布-Published\"}," +
                        "{\"value\": \"4\",\"label\": \"作废-Deleted\"}" + "]";
                extSettings.put(OPTION_ITEMS_KEY, JSONArray.parseArray(statusList));
                control.setDefaultVal("0");
            }
            control.setExtSettings(extSettings.toString());
            control.setInputSource(InputSourceEnum.input.name());
            if (col.getIsBuildIn() == 1) {
                control.setInputSource(InputSourceEnum.buildIn.name());
            }
            controls.add(control);
        }
        return controls;
    }

    /***
     * @description 根据实体生成formJSON(可以渲染成表单页面)
     * @param form 表单对象
     * @param fmControls 表单控件列表
     */
    public JSONArray generateJson(Form form, List<FormControl> fmControls) {
        JSONArray controls = new JSONArray();
        if (fmControls == null || fmControls.isEmpty()) {
            return controls;
        }
        //生成标题开始
        JSONObject formTitle = new JSONObject();
        formTitle.put("type", "static-text");
        formTitle.put("formItemFlag", false);
        formTitle.put("id", "MainFormTitle");
        JSONObject formTitleOptions = new JSONObject();
        formTitleOptions.put("name", "MainFormTitle");
        formTitleOptions.put("textAlign", "center");
        formTitleOptions.put("fontSize", "18px");
        formTitleOptions.put("hidden", true);
        formTitleOptions.put("formId", form.getFmId());
        formTitleOptions.put("textContent", form.getFmName() + " " + form.getEnName());
        formTitle.put("options", formTitleOptions);
        controls.add(formTitle);
        //生成栅格布局开始
        JSONObject grid = new JSONObject();
        grid.put("type", "grid");
        grid.put("icon", "grid");
        grid.put("id", "mainGrid");
        grid.put("category", "container");
        JSONObject gridOptions = new JSONObject();
        gridOptions.put("name", "mainGrid");
        gridOptions.put("gutter", form.getRowGutter());
        grid.put("options", gridOptions);
        JSONArray fields = new JSONArray();
        grid.put("cols", fields);
        controls.add(grid);
        int defaultSpan = 24 / form.getFmCols();
        int index = 0;
        //循环生成控件
        for (var control : fmControls) {
            index++;
            JSONObject field = new JSONObject();
            field.put("type", "grid-col");
            field.put("category", "container");
            field.put("icon", "grid-col");
            field.put("internal", true);
            field.put("id", "gridCol" + index);
            JSONObject gridColOptions = new JSONObject();
            gridColOptions.put("hidden", control.getIsHide() == 1);
            int span = defaultSpan;
            if (control.getColSpans() != null && control.getColSpans() > 0) {
                span = defaultSpan * control.getColSpans();
            }
            String strSettings = control.getExtSettings();
            if (StringUtils.isEmpty(strSettings)) {
                strSettings = "{}";
            }
            System.out.println("=========extSettings:" + strSettings);
            JSONObject extSettings = JSON.parseObject(strSettings);
            gridColOptions.put("span", span);
            gridColOptions.put("name", "gridCol" + index);
            field.put("options", gridColOptions);
            JSONArray widgetList = new JSONArray();
            //单个表单控件
            JSONObject widget = new JSONObject();
            widget.put("formItemFlag", true);
            JSONObject fieldOptions = new JSONObject();
            widget.put("options", fieldOptions);
            widget.put("type", control.getControlType());
            widget.put("id", control.getControlName());
            fieldOptions.put("colId", control.getColId());
            fieldOptions.put("name", control.getControlName());
            fieldOptions.put("label", control.getLabelText());
            fieldOptions.put("labelCn", control.getLabelText());
            fieldOptions.put("labelEn", control.getLabelEn());
            fieldOptions.put("labelHk", control.getLabelHk());
            fieldOptions.put("columnWidth", "200px");
            fieldOptions.put("type", control.getControlType());
            fieldOptions.put("hidden", control.getIsHide() == 1 ? true : false);
            boolean readonly = control.getIsReadonly() == 1 ? true : false;
            fieldOptions.put("readonly", readonly);
            fieldOptions.put("disabled", readonly); //只读的控件，同时也设为禁用，这样背景才变灰
            fieldOptions.put("required", control.getIsRequired() == 1 ? true : false);
            fieldOptions.put("clearable", extSettings.getBooleanValue("clearable", true));
            var selectOptions = extSettings.getJSONArray(OPTION_ITEMS_KEY);
            if (selectOptions != null) {
                fieldOptions.put(OPTION_ITEMS_KEY, selectOptions);
            }

            var refEntId = extSettings.getString(REF_ENT_ID_KEY);
            if (StringUtils.isNotEmpty(refEntId)) {
                fieldOptions.put("readonly", true);
                fieldOptions.put("appendButton", true);
                fieldOptions.put("buttonIcon", "el-more");
                fieldOptions.put(REF_ENT_ID_KEY, refEntId);
            }
            Integer maxLength = control.getMaxLength();
            if (maxLength != null && maxLength > 0) {
                fieldOptions.put("maxLength", maxLength);
                fieldOptions.put("showWordLimit", true);
            }
            String defaultVal = control.getDefaultVal();
            if (StringUtils.isNotEmpty(defaultVal)) {
                fieldOptions.put("defaultValue", defaultVal);
            }
            fieldOptions.put("title", control.getTitle());
            fieldOptions.put("placeholder", control.getPlaceholder());
            if (control.getControlType().equals(CTRL_TYPE_SELECT)) {
                fieldOptions.put("rows", 3);
            } else if (control.getControlType().equals(CTRL_TYPE_DATE)) {
                String format = extSettings.getString("format");
                if (StringUtils.isNotEmpty(format)) {
                    format = DATE_CONTROL_FORMAT_DEFAULT;
                }
                fieldOptions.put("valueFormat", format);
                fieldOptions.put("format", format);
            }
            widgetList.add(widget);
            field.put(WIDGET_LIST_KEY, widgetList);
            fields.add(field);
        }
        return controls;
    }

    @Override
    public BaseDao<Form> getRepository() {
        return formMapper;
    }
}